package com.rrd.itext.xmlBean.layoutBean;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPRow;
import com.itextpdf.text.pdf.PdfPTable;
import com.rrd.itext.obj.ResouceObject;
import com.rrd.itext.utils.HTMLParser;
import com.rrd.itext.utils.PDFBuilder;
import com.rrd.itext.utils.StyleUtil;
import com.rrd.itext.utils.enumeration.FontStyle;
import com.rrd.itext.xmlBean.layoutBean.iface.PdfElementParser;
import com.rrd.itext.xmlBean.layoutBean.iface.PrintOrder;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;

@XStreamAlias("HTMLBlock")
public class XmlHtmlBlock implements PrintOrder, PdfElementParser<List<Element>>{
    @XStreamAsAttribute
    @XStreamAlias("name")
    private String name;

    @XStreamAsAttribute
    @XStreamAlias("printOrder")
    private int printOrder;
    
    @XStreamAsAttribute
    @XStreamAlias("newLine")
    private boolean newLine;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrintOrder() {
        return printOrder;
    }

    public void setPrintOrder(int printOrder) {
        this.printOrder = printOrder;
    }

    public boolean isNewLine() {
        return newLine;
    }

    public void setNewLine(boolean newLine) {
        this.newLine = newLine;
    }

    @Override
    public List<Element> parse(PDFBuilder builder) throws Exception {
        List<Element> elements = new ArrayList<Element>();
        if (name == null || "".equals(name.trim())) {
            return elements;
        }
        if (!builder.getResourceMap().containsKey(name)) {
            return elements;
        }
        String htmlContent = ResouceObject.getDataContent(builder.getResourceMap(), name);
        //elements = HTMLParserHelper.getInstance().parseXHtml(htmlContent);
        elements = HTMLParser.parseHTML(htmlContent, builder.getFontProvider());
        for(Element element : elements){
            embedFont(element, builder.getFontMap());
        }
        return elements;
    }
    
    private Font createEmbedFont(Font f, Map<String, String> fontMap){
        BaseFont bFont = f.getBaseFont();
        if(bFont != null){
            return f;
        }
        String fontFamily;
        if(f.getFamily().equals(FontFamily.UNDEFINED)){
            fontFamily = "";
        }else{
            fontFamily = f.getFamilyname();
        }
        String fontStyle = FontStyle.getFontStyle(f.getStyle());
        BaseFont baseFont = StyleUtil.createBaseFont(fontFamily, fontStyle, fontMap);
        Font font = new Font(baseFont);
        font.setColor(f.getColor());
        font.setFamily(f.getFamilyname());
        font.setSize(f.getSize());
        font.setStyle(f.getStyle());
        return font;
    }

    private void embedFont(Element e, Map<String, String> fontMap){
        if(e == null || fontMap == null){
            return;
        }
        if(e instanceof Paragraph){
            Paragraph p = (Paragraph)e;
            Font f = createEmbedFont(p.getFont(), fontMap);
            p.setFont(f);
            for(int i = 0; i < p.size(); i ++){
                Element child = p.get(i);
                embedFont(child, fontMap);
            }
        }else if(e instanceof Phrase){
            Phrase p = (Phrase)e;
            Font f = createEmbedFont(p.getFont(), fontMap);
            p.setFont(f);
            for(int i = 0; i < p.size(); i ++){
                Element child = p.get(i);
                embedFont(child, fontMap);
            }
        }else if(e instanceof Chunk){
            Chunk c = (Chunk)e;
            Font f = createEmbedFont(c.getFont(), fontMap);
            c.setFont(f);
        }else if(e instanceof com.itextpdf.text.List){
            com.itextpdf.text.List l = (com.itextpdf.text.List)e;
            embedFont(l.getSymbol(), fontMap);
            List<Chunk> cs = l.getChunks();
            for(Chunk c : cs){
                embedFont(c, fontMap);
            }
        }else if(e instanceof com.itextpdf.text.List){
            com.itextpdf.text.List pl = (com.itextpdf.text.List)e;
            List<Chunk> cs = pl.getChunks();
            for(Chunk c : cs){
                embedFont(c, fontMap);
            }
        }else if(e instanceof PdfPTable){
            PdfPTable pt = (PdfPTable)e;
            for(Chunk c : pt.getChunks()){
                embedFont(c, fontMap);
            }
            for(PdfPRow row : pt.getRows()){
                for(PdfPCell cell : row.getCells()){
                    embedFont(cell, fontMap);
                }
            }
        }else if(e instanceof PdfPCell){
            PdfPCell cell = (PdfPCell)e;
            List<Element> ecs = cell.getColumn().getCompositeElements();
            
            if(ecs!=null) {
            for(Element ec : ecs){
                embedFont(ec, fontMap);
            }
            
        }
            embedFont(cell.getPhrase(), fontMap);
        }else{
            System.out.println("*********"+e.toString());
        }
    }
}
